﻿using EquipmentAlarmSystem.Service.Models;
using NModbus;
using System.Net.Sockets;
using System.Text.Json;

namespace 设备报警系统客户端
{
    public partial class ModbusTcp设备添加修改 : Form
    {
        public ModbusTcp设备添加修改()
        {
            InitializeComponent();
            //忽略其他线程执行UI的错误
            CheckForIllegalCrossThreadCalls = false;
        }

        private string id = "";

        public ModbusTcp设备添加修改(string id)
        {
            InitializeComponent();
            //忽略其他线程执行UI的错误
            CheckForIllegalCrossThreadCalls = false;
            this.id = id;
        }

        /// <summary>
        /// 判断是否未空
        /// </summary>
        /// <param name="o"></param>
        /// <returns></returns>
        private string iSNull(object o)
        {
            if (o is null)
            {
                return "-1";
            }
            return o.ToString()!;
        }
        private bool isNullBool(object o)
        {
            if (o is not null)
            {
                return bool.Parse(o.ToString()!);
            }
            return false;
        }

        private void LoadData()
        {
            var conf = JsonSerializer.Deserialize<DeviceInformationModusTcp>(Basic.HttpGet($"/Equipment/GetEquipment?id={id}"));


            this.Invoke(new Action(() =>
            {
                try
                {
                    DeviceInformation.Rows[0].Cells[0].Value = conf!.Id;
                    DeviceInformation.Rows[0].Cells[1].Value = conf!.Name;
                    DeviceInformation.Rows[0].Cells[2].Value = conf!.Describe;
                    //DeviceAddress.Rows[0].Cells[0].Value = Enum.GetName(conf.CpuType);
                    DeviceAddress.Rows[0].Cells[0].Value = conf.Ip;
                    DeviceAddress.Rows[0].Cells[1].Value = conf.Port;
                    DeviceAddress.Rows[0].Cells[2].Value = Enum.GetName(conf.FunctionCode);
                    DeviceAddress.Rows[0].Cells[3].Value = conf.SlaveAddress;
                    DeviceAddress.Rows[0].Cells[4].Value = conf.StartAddress;
                    DeviceAddress.Rows[0].Cells[5].Value = conf.NumberOfPoints;

                    Contacts.Rows.Clear();
                    if (conf.Contacts is not null)
                    {
                        foreach (var item in conf.Contacts)
                        {
                            int index = Contacts.Rows.Add();
                            Contacts.Rows[index].Cells[0].Value = item.Name;
                            Contacts.Rows[index].Cells[1].Value = item.EnableSms;
                            Contacts.Rows[index].Cells[2].Value = item.EnableDialing;
                        }
                    }

                    DataAddress.Rows.Clear();
                    if (conf.PointInformation is not null)
                    {
                        foreach (var item in conf.PointInformation)
                        {
                            int index = DataAddress.Rows.Add();
                            DataAddress.Rows[index].Cells[0].Value = item.Address;
                            DataAddress.Rows[index].Cells[1].Value = item.Content;
                            DataAddress.Rows[index].Cells[2].Value = item.IsEnabled;
                        }
                    }
                }
                catch (Exception)
                {

                }
            }));
        }

        private void ModbusTcp设备添加修改_Load(object sender, EventArgs e)
        {
            //添加默认行
            DeviceInformation.Rows.Add();

            DeviceAddress.Rows.Add();

            //添加联系人
            var contacts = Basic.Config.Contacts;

            if (contacts is not null && contacts.Count >= 1)
            {
                List<string> strings = ["未配置"];

                foreach (var item in contacts)
                {
                    strings.Add(item.Name);
                }
                Column4.DataSource = strings;
            }

            if (id.Length >= 4)
            {
                LoadData();
            }

            Column10.DataSource = Enum.GetNames(typeof(FunctionBlock));
        }

        private void btnPreserve_Click(object sender, EventArgs e)
        {
            Form form = new 验证服务();
            if (form.ShowDialog() != DialogResult.OK)
            {
                return;
            }
            DeviceInformationModusTcp configuration = new()
            {
                Id = iSNull(DeviceInformation.Rows[0].Cells[0].Value),
                Name = iSNull(DeviceInformation.Rows[0].Cells[1].Value),
                Describe = iSNull(DeviceInformation.Rows[0].Cells[2].Value),

                //设备连接信息
                Ip = iSNull(DeviceAddress.Rows[0].Cells[0].Value),
                Protocol = (EquipmentAlarmSystem.Service.Models.Enum.Protocol)Protocol.ModbusTcp,
                Port = short.Parse(iSNull(DeviceAddress.Rows[0].Cells[1].Value)),
                FunctionCode = (FunctionBlock)Enum.Parse(typeof(FunctionBlock), iSNull(DeviceAddress.Rows[0].Cells[2].Value), true),
                SlaveAddress = byte.Parse(iSNull(DeviceAddress.Rows[0].Cells[3].Value)),
                StartAddress = ushort.Parse(iSNull(DeviceAddress.Rows[0].Cells[4].Value)),
                NumberOfPoints = ushort.Parse(iSNull(DeviceAddress.Rows[0].Cells[5].Value))
            };
            configuration.PointInformation = new();
            //保存数据信息
            for (int i = 0; i < DataAddress.RowCount - 1; i++)
            {
                PointInformation pointInformation = new();

                string alarmAddress = iSNull(DataAddress.Rows[i].Cells[0].Value);

                if (alarmAddress.Length < 1)
                {
                    continue;
                }
                pointInformation.Address = alarmAddress;
                pointInformation.Content = iSNull(DataAddress.Rows[i].Cells[1].Value);
                pointInformation.IsEnabled = isNullBool(DataAddress.Rows[i].Cells[2].Value);
                configuration.PointInformation.Add(pointInformation);
            }

            configuration.Contacts = new();

            //添加联系人
            for (int i = 0; i < Contacts.RowCount - 1; i++)
            {
                if (iSNull(Contacts.Rows[i].Cells[0].Value) == "未配置")
                {
                    continue;
                }
                Contact contact = new();
                foreach (var item in Basic.Config.Contacts)
                {
                    if (item.Name == iSNull(Contacts.Rows[i].Cells[0].Value))
                    {
                        contact.Name = item.Name;
                        contact.EnableSms = isNullBool(Contacts.Rows[i].Cells[1].Value);
                        contact.EnableDialing = isNullBool(Contacts.Rows[i].Cells[2].Value);
                        configuration.Contacts.Add(contact);
                    }
                }
            }

            _ = Basic.HttpPostAsync("/Equipment/ModifyEquipmentModusTcp", configuration);

            this.Close();
        }

        private void DeviceAddress_CellEndEdit(object sender, DataGridViewCellEventArgs e)
        {
            DataGridViewRow row = DeviceAddress.Rows[e.RowIndex];

            if (e.ColumnIndex == 5)
            {
                if (iSNull(DeviceAddress.Rows[0].Cells[4].Value).Length >= 1 && iSNull(DeviceAddress.Rows[0].Cells[5].Value).Length >= 1)
                {
                    int len = int.Parse(iSNull(DeviceAddress.Rows[0].Cells[5].Value));
                    int num = int.Parse(iSNull(DeviceAddress.Rows[0].Cells[4].Value));
                    DataAddress.Rows.Clear();

                    for (int i = 0; i < len; i++)
                    {
                        int index = DataAddress.Rows.Add();
                        DataAddress.Rows[index].Cells[0].Value = num + i;
                    }
                }
            }
        }

        private void btnTest_Click(object sender, EventArgs e)
        {
            try
            {
                TcpClient client = new TcpClient(iSNull(DeviceAddress.Rows[0].Cells[0].Value), int.Parse(iSNull(DeviceAddress.Rows[0].Cells[1].Value)));

                var factory = new ModbusFactory();

                IModbusMaster master = factory.CreateMaster(client);

                FunctionBlock func = (FunctionBlock)Enum.Parse(typeof(FunctionBlock), iSNull(DeviceAddress.Rows[0].Cells[2].Value), true);

                byte SlaveAddress = byte.Parse(iSNull(DeviceAddress.Rows[0].Cells[3].Value));
                ushort StartAddress = ushort.Parse(iSNull(DeviceAddress.Rows[0].Cells[4].Value));
                ushort NumberOfPoints = ushort.Parse(iSNull(DeviceAddress.Rows[0].Cells[5].Value));

                IList<bool> bools = new List<bool>();

                if (func == FunctionBlock.Coils)
                {
                    //0123456
                    bools = master.ReadCoils(SlaveAddress, (ushort)(StartAddress), NumberOfPoints).ToList();
                }
                if (func == FunctionBlock.Inputs)
                {
                    bools = master.ReadInputs(SlaveAddress, (ushort)(StartAddress), NumberOfPoints).ToList();
                }

                int count = DataAddress.RowCount;

                this.Invoke(new Action(() =>
                {
                    for (int i = 0; i < bools.Count; i++)
                    {
                        if (i < count)
                        {
                            DataAddress.Rows[i].Cells[3].Value = (bool)bools[i];
                        }
                    }
                }));
            }
            catch (Exception)
            {
                MessageBox.Show("设备连接失败", "设备连接", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void btnImport_Click(object sender, EventArgs e)
        {

        }
    }
}

